﻿using Itech_Run.Application.Contracts.Shared.Dto;
using Itech_Run.Application.Shared;
using Itech_Run.Sys.Application.Contracts.Dto;
using Itech_Run.Sys.Application.Contracts.Service;
using Itech_Run.Sys.Domain.Entity;
using System.Linq.Expressions;
using System.Linq.Dynamic.Core;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
using Itech_Run.Sys.Domain.Manager;

namespace Itech_Run.Sys.Application.Service
{
    public class SysDictionaryService : BaseApplicationService<Sys_Dictionary>, ISysDictionaryService
    {
        private readonly IRepository<Sys_Dictionary, string> _sysDictionaryRepository;
        private readonly Sys_DictionaryManager _sysDictionaryManager;

        public SysDictionaryService(IRepository<Sys_Dictionary, string> sysDictionaryRepository, Sys_DictionaryManager sysDictionaryManager)
        {
            _sysDictionaryRepository = sysDictionaryRepository;
            _sysDictionaryManager = sysDictionaryManager;
        }

        public async Task DeleteAsync(string id)
        {
            try
            {
                var entity = await _sysDictionaryRepository.GetAsync(id, includeDetails: true);
                await _sysDictionaryRepository.DeleteAsync(entity);
            }
            catch { }
        }

        public async Task<SysDictionaryDto> GetAsync(string id)
        {
            var entity = await _sysDictionaryRepository.GetAsync(id, includeDetails: true);
            return ObjectMapper.Map<Sys_Dictionary, SysDictionaryDto>(entity);
        }

        public async Task<List<KeyValueDto>> GetCodeTypeListAsync()
        {
            return (await _sysDictionaryRepository.GetListAsync(p => p.CodeType == "1"))
                  .Select(s => new KeyValueDto
                  {
                      Key = s.Code,
                      Value = s.Name
                  }).ToList();
        }

        public async Task<List<SysDictionaryItemDto>> GetItemByCodeTypeAsync(string codeType)
        {
            return (await _sysDictionaryRepository.GetListAsync(p => p.IsActive == true && p.CodeType == codeType))
                  .Select(s => new SysDictionaryItemDto
                  {
                      Code = s.Code,
                      Name = s.Name,
                      Value = s.Value
                  }).ToList();
        }

        public async Task<PagedResultDto<SysDictionaryDto>> GetListAsync(SysDictionaryListDto listDto)
        {
            if (string.IsNullOrEmpty(listDto.Sorting)) listDto.Sorting = "CodeType asc,Sort asc";
            Expression<Func<Sys_Dictionary, bool>> curExpression = s => s.IsShow == true;
            if (listDto.Category != null)
                curExpression = curExpression.And(s => s.Category == listDto.Category);
            if (!string.IsNullOrEmpty(listDto.CodeType))
                curExpression = curExpression.And(s => s.CodeType == listDto.CodeType);
            if (!string.IsNullOrEmpty(listDto.Code))
                curExpression = curExpression.And(s => s.Code.Contains(listDto.Code));
            if (!string.IsNullOrEmpty(listDto.Name))
                curExpression = curExpression.And(s => s.Name.Contains(listDto.Name));
            if (listDto.IsActive != null)
                curExpression = curExpression.And(s => s.IsActive == listDto.IsActive);

            var query = (await _sysDictionaryRepository.WithDetailsAsync()).WhereIf(true, curExpression).OrderBy(listDto.Sorting);
            var items = ObjectMapper.Map<List<Sys_Dictionary>, List<SysDictionaryDto>>(query.PageBy(listDto.SkipCount, listDto.MaxResultCount).ToList());

            List<Sys_Dictionary> dictionaries = await GetDictionariesAsync();
            items.ForEach(item =>
            {
                //字典类型 CodeType=3
                item.CategoryName = dictionaries.Where(p => p.CodeType == "3" && p.Code == item.Category.ToString()).FirstOrDefault()?.Name ?? "";
                //字典类别 CodeType=1
                item.CodeTypeName = dictionaries.Where(p => p.CodeType == "1" && p.Code == item.CodeType).FirstOrDefault()?.Name ?? "";
            });
            return new PagedResultDto<SysDictionaryDto>(query.Count(), items);
        }

        private async Task<List<Sys_Dictionary>> GetDictionariesAsync()
        {
            return (await _sysDictionaryRepository.GetListAsync(p => p.IsActive == true && (p.CodeType == "1" || p.CodeType == "3"))).ToList();
        }

        public async Task<SysDictionaryDto> InsertAsync(SysDictionaryCreateDto dto, string operateUser)
        {
            var entity = ObjectMapper.Map<SysDictionaryCreateDto, Sys_Dictionary>(dto);
            await _sysDictionaryManager.Check_UniqueAsync(entity);
            SetInsertBy(entity, operateUser);
            var result = await _sysDictionaryRepository.InsertAsync(entity);
            return ObjectMapper.Map<Sys_Dictionary, SysDictionaryDto>(result);
        }

        public async Task<SysDictionaryDto> UpdateAsync(SysDictionaryUpdateDto dto, string operateUser)
        {
            var entity = await _sysDictionaryRepository.GetAsync(dto.Id, includeDetails: true);
            ObjectMapper.Map(dto, entity);
            await _sysDictionaryManager.Check_UniqueAsync(entity);
            SetUpdateBy(entity, operateUser);

            var result = await _sysDictionaryRepository.UpdateAsync(entity);
            return ObjectMapper.Map<Sys_Dictionary, SysDictionaryDto>(result);
        }
    }
}
